home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Network / QUE / Basic / quemail.c < prev    next >
C/C++ Source or Header  |  1989-10-01  |  10KB  |  549 lines

  1. /*
  2. ------------------------------------------------------------
  3. Copyright ) 1989 Rob Kassel, Mike McCandless and the Massachusetts Institute of Technology
  4.  
  5. Permission to use, copy, modify, and distribute this software and its documentation for any purpose without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.  The authors and M.I.T. make no representations about the suitability of this software for any purpose.  It is provided Ras isS without express or implied warranty.
  6. ------------------------------------------------------------
  7. */
  8.  
  9. #include "mail.h"
  10.  
  11. struct {
  12.     int num;
  13.     char nme[20][40];
  14. } theHdrFilter;
  15.  
  16.  
  17. char tBuf[MAXLINE];
  18. char *hdrLnPtrs[MAXLINE];
  19. FILE *fpOut, *fpTemp;
  20. char glbBuf[MAXLINE];
  21. int glbFlag;
  22. struct memBuf *myMemory;
  23.  
  24. main(argc,argv) 
  25. int argc;
  26. char *argv[];
  27.  
  28. {
  29. char pLine[MAXLINE],pName[20],*aBuf;
  30. char dirName[255];
  31. int done,nxtMsg,nxtRdMsg,lineNum,fd;
  32. time_t t;
  33. char tme[15];
  34. char nme[255];
  35. char mailDropName[MAXNAME],theUserName[MAXNAME];
  36. int numChars = 0;
  37. int msgPart = 2;        /*Start with a second part to the message*/
  38.  
  39.  
  40.  
  41. /*analyze on-line arguments*/
  42.  
  43. Init();
  44. parseArgs(argc,argv,mailDropName,theUserName,argv[0]);
  45.  
  46.  
  47. myMemory = allocBuf(MAXLINE,100);
  48.  
  49. /*Now I must find a unique file name, based on the time...*/
  50. fd = createUniqFile(argv[0],nme,mailDropName);
  51.  
  52. fpOut = fopen(nme,"w");
  53. if (fpOut == NULL) {
  54.     strcpy(errBuf,"Can't open mail file.\n");
  55.     errorParser(errBuf);
  56. }
  57. chmod(nme,0666);
  58.  
  59.  
  60. sprintf(tBuf,"X-Mac-To: %s\n",theUserName);
  61. storeStr(tBuf,myMemory);
  62. fprintf(fpOut,"X-Mac-To: %s\n",theUserName);
  63.  
  64.  
  65. /*Now, I must interpret the mail header..*/
  66. lineNum = 0;
  67. done = FALSE;
  68. getline(pLine,MAXLINE);    /*Gets rid of From *** Unix 1st line*/
  69.  
  70.  
  71. while (getline(pLine,MAXLINE) != NULL) {
  72.     if (done) {        /*Done reading the header*/
  73.         fputs(pLine,fpOut);
  74.         numChars+=strlen(pLine)+1;
  75.         if (numChars >= MAXMSGLENGTH) {
  76.             close(fd);
  77.             fclose(fpOut);
  78.  
  79.             fd = createUniqFile(argv[0],nme,mailDropName);
  80.  
  81.             fpOut = fopen(nme,"w");
  82.             if (fpOut == NULL) {
  83.                 strcpy(errBuf,"Can't open mail file.\n");
  84.                 errorParser(errBuf);
  85.             }
  86.             chmod(nme,0666);
  87.             dumpAnotherHeader(fpOut,msgPart);
  88.             msgPart++;
  89.             numChars = 0;
  90.         }
  91.     }
  92.  
  93.     else {
  94.         if (strlen(pLine) == 1 && (int) pLine[0] == 10) {
  95. /*A blank line indicates the beginning of the body*/
  96.             dealWithHeader(lineNum);
  97.             fprintf(fpOut,"\n");
  98.             storeStr("\n",myMemory);
  99.             done = TRUE;    
  100.         }
  101.         aBuf = alcCh(MAXLINE);
  102.         strcpy(aBuf,pLine);
  103.         hdrLnPtrs[lineNum] = aBuf;    
  104.         lineNum++;
  105.         if (lineNum == MAXLINE) {
  106.             strcpy(errBuf,"Mail header too long.\n");
  107.             errorParser(errBuf);
  108.         }
  109.     }
  110. }
  111.  
  112. close(fd);
  113. fclose(fpOut);
  114. }
  115.  
  116.  
  117.  
  118. dumpAnotherHeader(fpOut,partNum)
  119.  
  120. FILE *fpOut;
  121. int partNum;
  122.  
  123. {
  124. char lne[MAXLINE];
  125. char buf[30];
  126. int foundIt = FALSE;
  127.  
  128.  
  129.  
  130. resetBuf(myMemory);
  131.  
  132. while(readStr(lne,myMemory) != 0) {
  133.     if (!strncmp(lne,SUBJECT,strlen(SUBJECT))) {
  134.         foundIt = TRUE;
  135.         sprintf(buf," (Part %d)\n",partNum);    
  136.         strp1Ch(lne);
  137.         strcat(lne,buf);    
  138.         fprintf(fpOut,lne);
  139.                 buf[0] = NULL;
  140.           }
  141.  
  142.     else 
  143.         if ((strlen(lne) == 1) && (*lne == 10) && !foundIt) {
  144.             fprintf(fpOut,"Subject: Continued Message (Part %d)\n",
  145.                 partNum);
  146.             fprintf(fpOut,lne);
  147.               }
  148.         else  fprintf(fpOut,lne);
  149.       }
  150. }
  151.  
  152.  
  153.  
  154.  
  155. createUniqFile(progName,nme,mailDropName)
  156.  
  157. char *progName,*nme,*mailDropName;
  158.  
  159.  
  160. {
  161. char tme[15];
  162. time_t t;
  163. int fd;
  164. char dirName[MAXLINE];
  165.  
  166.  
  167.  
  168. sprintf(dirName,"%s/%s",theDir,mailDropName);
  169.  
  170. t = time((time_t *)0);
  171. t = t % aYearInS;
  172.  
  173. while(1) {
  174.     sprintf(tme,"%s",fltr(encode((long)t)));
  175.     sprintf(nme,"%s/%s%s",dirName,MSGHDR,tme);
  176.  
  177.     fd = open(nme,O_WRONLY+O_EXCL+O_CREAT,S_IRUSR+S_IWUSR+S_IRGRP+S_IWGRP);
  178.  
  179.     if (fd == -1 && errno != EEXIST && errno != ENOENT) {
  180.         sprintf(errBuf,"%s: %s\n",progName,sys_errlist[errno]);
  181.         errorParser(errBuf);
  182.     }
  183.  
  184.     if (fd == -1 && errno == ENOENT) {
  185.         sprintf(errBuf,"No such mail drop %s.\n",mailDropName);
  186.         errorParser(errBuf);
  187.     }
  188.  
  189.     if (fd == -1 && errno == EEXIST)
  190.         t++;
  191.  
  192.     if (fd != -1)
  193.         break;
  194. }
  195.  
  196. return(fd);
  197. }
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. dealWithHeader(numLines) 
  205. int numLines;
  206.  
  207. {
  208. int lp,foldCount,unFoldCount;
  209. char buf[MAXLINE],ch,c;
  210. char *unFold[MAXLINE],*pS;
  211.  
  212.  
  213. /*Parse the entire header, extracting what I need*/
  214.  
  215. foldCount = 0;
  216. unFoldCount = -1;
  217.  
  218.  
  219. while (foldCount < numLines) {
  220.     ch = *hdrLnPtrs[foldCount];    /*The first char of the line*/
  221.     if ((int)ch != 32 && (int)ch != 9) {
  222.         unFoldCount++;
  223.         unFold[unFoldCount] = alcCh(MAXLINE);
  224.         strcpy(unFold[unFoldCount],hdrLnPtrs[foldCount]);
  225.         strp1Ch(unFold[unFoldCount]);
  226.     }
  227.     else {
  228.         strcat(unFold[unFoldCount],hdrLnPtrs[foldCount]);
  229.         strp1Ch(unFold[unFoldCount]);
  230.         if(strlen(unFold[unFoldCount]) >= MAXLINE)
  231.             printf("Unfolded line too long; data lost.\n");
  232.     }
  233.     foldCount++;
  234.  
  235. }
  236.  
  237.  
  238. glbFlag = 0;
  239. lp = 0;
  240.  
  241. for (lp=0;lp<=unFoldCount;lp++)  {
  242.     parseHdrLine(unFold[lp],0);
  243. }
  244.  
  245. fprintf(fpOut,"%s",glbBuf);
  246. storeStr(glbBuf,myMemory);
  247.  
  248. for (lp=0;lp<=unFoldCount;lp++) 
  249.     parseHdrLine(unFold[lp],1);
  250.  
  251. }
  252.  
  253.  
  254. parseHdrLine(pLne,mde)
  255.  
  256. char* pLne;
  257. int mde;
  258.  
  259. {
  260. int lp,allow;
  261. char mailBx[MAXLINE];
  262. char buf[MAXLINE + 20];
  263.  
  264. allow = TRUE;
  265.  
  266.  
  267. /*I need to look for From:
  268.              Reply To:
  269.     to create the the X-Mac-From: field in the Mac's message file.
  270. */
  271.  
  272.  
  273. if (!glbFlag && !mde)  {
  274.     if (strncmp(pLne,aRPLTO,strlen(aRPLTO)) == 0) {
  275.         strcpy(mailBx,rmSpce(pLne+strlen(aRPLTO)));
  276.         sprintf(glbBuf,"X-Mac-From: %s\n",parseReplyTo(mailBx));    
  277.         glbFlag = 1;
  278.     }
  279.     else
  280.         if (strncmp(pLne,aFROM,strlen(aFROM)) == 0) {
  281.             strcpy(mailBx,rmSpce(pLne + strlen(aFROM)));
  282.             sprintf(buf,"X-Mac-From: %s\n",parseReplyTo(mailBx));    
  283.             strcpy(glbBuf,buf);
  284.         }
  285. }
  286.  
  287.  
  288. for(lp=0;lp<theHdrFilter.num;lp++)
  289.     if (!strncmp(pLne,theHdrFilter.nme[lp],strlen(theHdrFilter.nme[lp]))) {
  290.         allow = FALSE;
  291.         break;
  292.     }
  293.  
  294.  
  295. if (allow && mde) {
  296.     sprintf(tBuf,"%s\n",pLne);
  297.     storeStr(tBuf,myMemory);
  298.     fprintf(fpOut,"%s\n",pLne);
  299. }
  300. }
  301.  
  302.  
  303. parseArgs(argc,argv,drop,user,progName)
  304.  
  305. int argc;
  306. char *argv[];
  307. char *drop,*user;
  308. char *progName;
  309.  
  310. {
  311. int lp;
  312. int errr;
  313. char buf[MAXNAME],ch;
  314.  
  315. errr = FALSE;
  316. *user = (char)0;
  317. *drop = (char)0;
  318.  
  319. for(lp=1;lp<argc;lp++) {
  320.     if (*argv[lp] != '-') {
  321.         errr = TRUE;
  322.     }
  323.     else {
  324.         ch = *(argv[lp] + 1);
  325.         if (ch == 0) {
  326.             errr = TRUE;
  327.             break;    
  328.         }
  329.         if (ch != dropChar && ch != userChar) {
  330.             errr = TRUE;
  331.             break;
  332.         }
  333.  
  334.         if(ch == dropChar) {
  335.             if (*drop != 0) {
  336.                 errr = TRUE;
  337.                 break;
  338.             }
  339.             if (strlen(argv[lp]) == 2) {
  340.                 strcpy(buf,argv[lp + 1]);
  341.                 lp++;
  342.             }
  343.             else
  344.                 strcpy(buf,argv[lp] + 2);
  345.             
  346.             strcpy(drop,makeLower(buf));
  347.             if(*buf == '-')
  348.                 errr = TRUE;
  349.         }
  350.         
  351.         if(ch == userChar){
  352.             if (*user != 0) {
  353.                 errr = TRUE;
  354.                 break;
  355.             }
  356.  
  357.             strcpy(buf,"\0");
  358.             if (strlen(argv[lp]) > 2) {
  359.                 strcpy(buf,argv[lp] + 2);
  360.                 strcat(buf,theSpace);
  361.             }
  362.                 
  363.             lp++;
  364.             if(lp < argc) 
  365.                 while(*argv[lp] != '-' && lp < argc) {
  366.                 strcat(buf,argv[lp]);
  367.                 if((lp+1) < argc)
  368.                     if((*argv[lp+1] != '-'))
  369.                     strcat(buf,theSpace);
  370.                 lp++;
  371.                 if (lp == argc)
  372.                     break;
  373.                 }
  374.  
  375.             if (lp != argc) lp--;
  376.             
  377.             strcpy(user,buf);
  378.             if(*buf == '-')
  379.                 errr = TRUE;
  380.         }
  381.     }
  382. }
  383.  
  384. if (errr || *user == (char)0 || *drop == (char)0) {
  385.     sprintf(errBuf,"Usage: |%s -%c maildrop -%c username.\n",progName,dropChar,userChar);
  386.     errorParser();
  387. }
  388. }
  389.  
  390.  
  391. char* encode(y)
  392.  
  393. long y;
  394.  
  395. {
  396. /*encode a long number into a base-36 format*/
  397. /*0...9,A....Z*/
  398. int z,m;
  399. char *c;
  400.  
  401. c = alcCh(MAXLINE);
  402.  
  403. m = 0;
  404. while (y>0) {
  405.         z = y % 36;
  406.         y -= z;
  407.         y /= 36;
  408.         if (z > 9)
  409.                 *(c+m) = (char) z + 55;
  410.         else
  411.                 *(c + m) = (char) z + 48;
  412.         m++;
  413. }
  414.  
  415. *(c+m) = (char)0;
  416. return(flp(c));
  417. }
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424. Init() {
  425.     
  426. char buf[1000];
  427.  
  428.  
  429.     theHdrFilter.num = 6;
  430.     strcpy(theHdrFilter.nme[0],"Return\0");
  431.     strcpy(theHdrFilter.nme[1],"Received\0");
  432.     strcpy(theHdrFilter.nme[2],"Message-Id\0");
  433.     strcpy(theHdrFilter.nme[3],"Apparently\0");
  434.     strcpy(theHdrFilter.nme[4],"Status\0");
  435.     strcpy(theHdrFilter.nme[5],"Mail\0");
  436.     
  437.     /*scanf("%[^\n]%*c",buf);*/
  438. }
  439.  
  440.  
  441.  
  442. char* parseReplyTo(msg)
  443.  
  444. char *msg;
  445. {
  446. struct fld fldRp,*pFldRp;
  447. int lp,lp1;
  448. int tpe,contin;
  449. char *x;
  450. struct {
  451.     char adr[MAXLINE];
  452.     char phr[MAXLINE];
  453. }    xmFormat;    /*Mac's format: phr <adr>\n*/
  454. char tBuf[MAXLINE];
  455. char *pBuf;
  456. char *buf;
  457. int canCmnt;
  458.  
  459.  
  460. buf = alcCh(MAXLINE); 
  461.  
  462. pFldRp = &fldRp;
  463.  
  464. strcpy(pFldRp->buf,msg);
  465. fieldParse(pFldRp);
  466.  
  467.  
  468. /*
  469. struct fld {
  470.         int cnt;                /Holds the number of items found in field/
  471.         char buf[MAXLINE];      /Holds the orig. text of field/
  472.         struct fldItem {
  473.                 char *txt;
  474.                 int tpe;
  475.         }       itm[50];         /Holds each item description/
  476. };
  477. */
  478.  
  479.  
  480. *xmFormat.adr = '\0';
  481. *xmFormat.phr = '\0';
  482.  
  483. for(lp=0;lp<pFldRp->cnt;lp++)
  484.     if (pFldRp->itm[lp].tpe == addrS) {
  485.         sprintf(xmFormat.adr,"<%s>",pFldRp->itm[lp].txt);
  486.         break;
  487.     }
  488.  
  489. if (!strlen(xmFormat.adr)) {
  490.     for(lp=0;lp<pFldRp->cnt;lp++)
  491.         if (pFldRp->itm[lp].tpe == atAtm) {
  492.             sprintf(xmFormat.adr,"<%s>",pFldRp->itm[lp].txt);
  493.             break;
  494.         }
  495. }
  496.  
  497. else
  498.     for(lp=0;lp<pFldRp->cnt;lp++)
  499.         if (pFldRp->itm[lp].tpe == atAtm) {
  500.             sprintf(xmFormat.phr,"%s",pFldRp->itm[lp].txt);
  501.             break;
  502.         }
  503.     
  504.  
  505.  
  506. if (!strlen(xmFormat.phr))
  507.     for(lp=0;lp<pFldRp->cnt;lp++)
  508.         if (pFldRp->itm[lp].tpe == cmnt) {
  509.             sprintf(xmFormat.phr,"%s",pFldRp->itm[lp].txt);
  510.             break;
  511.         }
  512.  
  513. if (!strlen(xmFormat.phr))
  514.     pBuf = xmFormat.phr;
  515. else
  516.     pBuf = tBuf;
  517.  
  518. contin = 1;
  519. for (lp1=0;lp1<pFldRp->cnt;lp1++)  {
  520.     if (!contin)
  521.         break;
  522.     if (pFldRp->itm[lp1].tpe == atm) {
  523.         contin = 0;
  524.         lp = 0;
  525.         while(pFldRp->itm[lp + lp1].tpe == atm) {
  526.             strcat(pBuf,pFldRp->itm[lp + lp1].txt);
  527.             strcat(pBuf," \0");
  528.             lp++;
  529.             if (lp + lp1 == pFldRp->cnt) break;
  530.         }
  531.         strp1Ch(pBuf);
  532.     }
  533. }
  534.  
  535. if (!strlen(xmFormat.adr) && strlen(tBuf))
  536.     sprintf(xmFormat.adr,"<%s>",tBuf);
  537.  
  538. if (!strlen(xmFormat.adr) && strlen(xmFormat.phr))
  539.     sprintf(xmFormat.adr,"<%s>",xmFormat.phr);
  540.  
  541. if (!strlen(xmFormat.phr) && strlen(xmFormat.adr)) {
  542.     strncpy(xmFormat.phr,xmFormat.adr + 1,strlen(xmFormat.adr) - 2);
  543.     *(xmFormat.phr + strlen(xmFormat.adr) - 2) = 0;
  544. }
  545.     
  546. sprintf(buf,"%s %s",xmFormat.phr,xmFormat.adr);
  547. return(buf);
  548. }
  549.